﻿package frEngine.loaders.away3dMd5
{
    import __AS3__.vec.*;
    import flash.geom.*;
    import flash.utils.*;
    import frEngine.loaders.away3dMd5.md5Data.*;
    import frEngine.math.*;

    public class MD5AnimByteArrayParser extends MD5AnimParserBase
    {
        public var animationSet:SkeletonAnimationSet;
        private var parsedTrackNum:int = 0;
        public var headAndJoins:HeadJoins;
        private var numtrack:int;
        private var _clipNodeList:Vector.<SkeletonClipNode>;
        public static const parseTypeValue:int = 8448;

        public function MD5AnimByteArrayParser(param1:String)
        {
            super(param1);
            return;
        }// end function

        override public function proceedParsing() : Boolean
        {
            var _loc_1:Boolean = false;
            var _loc_2:SkeletonClipNode = null;
            if (this.parsedTrackNum < this.numtrack && this.numtrack > 0)
            {
                _loc_1 = readClipFrames(_curClip);
                if (_loc_1)
                {
                    _curClip.setLoaded();
                    var _loc_3:String = this;
                    var _loc_4:* = this.parsedTrackNum + 1;
                    _loc_3.parsedTrackNum = _loc_4;
                    if (this.parsedTrackNum < this.numtrack)
                    {
                        _loc_2 = this._clipNodeList[this.parsedTrackNum];
                        setClip(_loc_2);
                    }
                    else
                    {
                        _curClip = null;
                        this._clipNodeList = null;
                    }
                }
            }
            return this.parsedTrackNum >= this.numtrack;
        }// end function

        public function proceedParsingHead(param1:ByteArray) : Boolean
        {
            _bytes = param1;
            this.headAndJoins = parseHeadAndJoints(_bytes);
            if (!this.headAndJoins)
            {
                return false;
            }
            this._numAnimatedComponents = this.headAndJoins.numAnimatedComponents;
            this._numJoints = this.headAndJoins.numJoints;
            this.hierarchy = this.headAndJoins.joinsList;
            this.baseFrameData = readBaseFrame(this.headAndJoins, _bytes);
            if (!this.animationSet)
            {
                this.animationSet = new SkeletonAnimationSet();
            }
            else
            {
                this.animationSet.dispose();
            }
            this.animationSet.init(this.headAndJoins.tracksList);
            this.readHeadClips(this.headAndJoins.tracksList);
            this.parsedTrackNum = 0;
            if (this.numtrack > 0)
            {
                setClip(this._clipNodeList[0]);
            }
            else
            {
                _curClip = null;
            }
            return true;
        }// end function

        private function readHeadClips(param1:Vector.<SkeletonClipNode>) : void
        {
            var _loc_4:SkeletonClipNode = null;
            var _loc_2:* = param1.length;
            if (_loc_2 == 0)
            {
                this.numtrack = 0;
                return;
            }
            this._clipNodeList = new Vector.<SkeletonClipNode>;
            var _loc_3:int = 0;
            while (_loc_3 < _loc_2)
            {
                
                _loc_4 = param1[_loc_3];
                if (_loc_4.isInHead)
                {
                    this._clipNodeList.push(_loc_4);
                }
                _loc_3++;
            }
            this.numtrack = this._clipNodeList.length;
            return;
        }// end function

        override public function clear() : void
        {
            this.headAndJoins = null;
            super.clear();
            return;
        }// end function

        public static function readBaseFrame(param1:HeadJoins, param2:ByteArray) : Vector.<BaseFrameData>
        {
            var _loc_4:BaseFrameData = null;
            var _loc_7:Vector3D = null;
            var _loc_8:Quaternion = null;
            var _loc_9:Vector3D = null;
            var _loc_3:* = param1.numJoints;
            var _loc_5:* = new Vector.<BaseFrameData>(_loc_3, true);
            var _loc_6:int = 0;
            while (_loc_6 < _loc_3)
            {
                
                _loc_4 = new BaseFrameData();
                _loc_7 = new Vector3D();
                _loc_7.x = param2.readFloat();
                _loc_7.y = param2.readFloat();
                _loc_7.z = param2.readFloat();
                _loc_4.position = _loc_7;
                _loc_8 = new Quaternion();
                _loc_8.x = param2.readFloat();
                _loc_8.y = param2.readFloat();
                _loc_8.z = param2.readFloat();
                _loc_4.orientation = _loc_8;
                _loc_9 = new Vector3D();
                if (param1.hasScaledBone)
                {
                    _loc_9.x = param2.readFloat();
                    _loc_9.y = param2.readFloat();
                    _loc_9.z = param2.readFloat();
                }
                else
                {
                    _loc_9.x = 1;
                    _loc_9.y = 1;
                    _loc_9.z = 1;
                }
                _loc_4.scale = _loc_9;
                _loc_5[_loc_6] = _loc_4;
                _loc_6++;
            }
            return _loc_5;
        }// end function

        public static function parseHeadAndJoints(param1:ByteArray) : HeadJoins
        {
            var i:int;
            var _clip:SkeletonClipNode;
            var trackName:String;
            var frameNum:int;
            var fightOnFrame:int;
            var skipFrame:int;
            var isInHead:Boolean;
            var data:HierarchyData;
            var _bytes:* = param1;
            _bytes.endian = Endian.LITTLE_ENDIAN;
            _bytes.position = 0;
            var headJoins:* = new HeadJoins();
            headJoins.magic = _bytes.readUnsignedShort();
            headJoins.version = _bytes.readUnsignedShort();
            if (headJoins.version >= 256 && headJoins.version < 260)
            {
                headJoins.version = headJoins.version - 256;
                headJoins.hasScaledBone = true;
            }
            headJoins.isCompress = checkIsCompressBone(headJoins.magic, headJoins.version);
            if (headJoins.isCompress)
            {
                _bytes.position = 0;
                try
                {
                    _bytes.uncompress();
                }
                catch (e:Error)
                {
                    return null;
                }
                headJoins.magic = _bytes.readUnsignedShort();
                headJoins.version = _bytes.readUnsignedShort();
                if (headJoins.version >= 256 && headJoins.version < 260)
                {
                    headJoins.version = headJoins.version - 256;
                    headJoins.hasScaledBone = true;
                }
                if (headJoins.magic != parseTypeValue)
                {
                    return null;
                }
            }
            var numJoins:* = _bytes.readUnsignedShort();
            headJoins.numAnimatedComponents = _bytes.readUnsignedShort();
            var tracknum:* = _bytes.readUnsignedShort();
            var joinsList:* = new Vector.<HierarchyData>(numJoins, true);
            if (headJoins.version == 3)
            {
                i;
                while (i < tracknum)
                {
                    
                    trackName = _bytes.readUTF();
                    frameNum = _bytes.readUnsignedShort();
                    fightOnFrame = _bytes.readUnsignedShort();
                    skipFrame = _bytes.readUnsignedShort();
                    isInHead = _bytes.readBoolean();
                    _clip = new SkeletonClipNode(0, (frameNum - 1), trackName, joinsList, fightOnFrame, frameNum, isInHead, skipFrame);
                    headJoins.tracksList.push(_clip);
                    i = (i + 1);
                }
                i;
                while (i < numJoins)
                {
                    
                    data = new HierarchyData();
                    data.name = _bytes.readUTF();
                    data.parentIndex = _bytes.readShort();
                    data.flags = _bytes.readUnsignedShort();
                    data.startIndex = _bytes.readUnsignedShort();
                    joinsList[i] = data;
                    i = (i + 1);
                }
            }
            else
            {
                if (headJoins.version == 1)
                {
                    i;
                    while (i < tracknum)
                    {
                        
                        trackName = readString(_bytes);
                        frameNum = _bytes.readUnsignedShort();
                        skipFrame = _bytes.readUnsignedShort();
                        _clip = new SkeletonClipNode(0, (frameNum - 1), trackName, joinsList, 0, frameNum, true, skipFrame);
                        headJoins.tracksList.push(_clip);
                        i = (i + 1);
                    }
                }
                else if (headJoins.version == 2)
                {
                    i;
                    while (i < tracknum)
                    {
                        
                        trackName = readString(_bytes);
                        frameNum = _bytes.readUnsignedShort();
                        fightOnFrame = _bytes.readUnsignedShort();
                        skipFrame = _bytes.readUnsignedShort();
                        _clip = new SkeletonClipNode(0, (frameNum - 1), trackName, joinsList, fightOnFrame, frameNum, true, skipFrame);
                        headJoins.tracksList.push(_clip);
                        i = (i + 1);
                    }
                }
                i;
                while (i < numJoins)
                {
                    
                    data = new HierarchyData();
                    data.name = readString(_bytes);
                    data.parentIndex = _bytes.readShort();
                    data.flags = _bytes.readUnsignedShort();
                    data.startIndex = _bytes.readUnsignedShort();
                    joinsList[i] = data;
                    i = (i + 1);
                }
            }
            headJoins.joinsList = joinsList;
            return headJoins;
        }// end function

        public static function readString(param1:ByteArray) : String
        {
            var _loc_2:String = null;
            var _loc_6:int = 0;
            var _loc_3:int = 0;
            var _loc_4:* = param1.position;
            var _loc_5:int = 500;
            while (_loc_3 < _loc_5)
            {
                
                _loc_2 = param1.readMultiByte(1, "gb2312");
                if (_loc_2 == "\\")
                {
                    _loc_6 = param1.position - _loc_4 - 1;
                    param1.position = _loc_4;
                    _loc_2 = param1.readMultiByte(_loc_6, "gb2312");
                    param1.position = param1.position + 2;
                    break;
                }
                _loc_3++;
            }
            if (_loc_3 == _loc_5)
            {
                throw new Error("3dmax输出有误，字符串没有加\\");
            }
            return _loc_2;
        }// end function

    }
}
